/*
 * Copyright (C) 2003, Velocityme Partnership
 * PersonSessionBean.java
 *
 * Created on 14 April 2003, 07:20
 */

package com.velocityme.session;

import com.velocityme.entity.ChangeDeltaItemTypeBean;
import com.velocityme.entity.ChangeDeltaTypeBean;
import com.velocityme.entity.PermissionBean;
import javax.ejb.*;
import javax.naming.*;
import java.util.*;
import com.velocityme.interfaces.*;
import com.velocityme.utility.InvalidKeyException;
import com.velocityme.utility.PermissionDeniedException;
import com.velocityme.valueobjects.*;
import java.rmi.RemoteException;

/**
 *
 * @author  Robert Crida Work
 * @ejb.bean
 *           type="Stateless"
 *           cmp-version="2.x"
 *           name="PersonSession"
 *           jndi-name="ejb/PersonSession"
 *           view-type="local"
 *           transaction-type="Container"
 * @ejb.transaction type="Required"
 *
 * @ejb.util generate="physical"
 */
public class PersonSessionBean implements SessionBean {
    
    private SessionContext m_context;
    
    private SearchSessionLocal m_searchSessionLocal;

    private PermissionLocal m_permissionPersonCreate;
    private PermissionLocal m_permissionPersonEdit;
    private PermissionLocal m_permissionNodeView;

    /**
     * If the user has permission to create a new Person in the specified parent
     * node then go ahead and create it and log an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_parentNode The node which will contain the new Person
     * @param p_personValue The value details for the Person part of the person
     *
     * @ejb.interface-method view-type="local"
     **/
    public PersonLocal createPerson(KeySessionLocal p_keyLocal,
                                    NodeLocal p_parentNodeLocal,
                                    com.velocityme.valueobjects.PersonValue p_personValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            if (m_searchSessionLocal.getAssignedPermissionsLocal(p_keyLocal, p_parentNodeLocal).contains(m_permissionPersonCreate)) {
                DBObjectLocal dBObjectLocal = DBObjectUtil.getLocalHome().create();
                ContactableValue contactableValue = p_personValue.getContactableValue();
                contactableValue.setType("Person");
                contactableValue.getNodeValue().setFinalType("Person");
                NodeValue nodeValue = contactableValue.getNodeValue();
                nodeValue.setType("Contactable");
                nodeValue.setName(p_personValue.getFirstName() + " " + p_personValue.getLastName());
                NodeLocal nodeLocal = NodeUtil.getLocalHome().create(dBObjectLocal, nodeValue, p_parentNodeLocal);
                nodeValue.setNodeId(nodeLocal.getNodeId());
                ContactableSessionUtil.getLocalHome().create().calcContactDetailChanges(contactableValue, null);
                ContactableLocal contactableLocal = ContactableUtil.getLocalHome().create(nodeLocal, contactableValue);
                contactableValue.setContactableId(contactableLocal.getContactableId());
                PersonLocal personLocal = PersonUtil.getLocalHome().create(contactableLocal, p_personValue);
                ChangeDeltaLocal changeDeltaLocal = ChangeDeltaUtil.getLocalHome().create(new Date(), ChangeDeltaTypeBean.CREATE, p_keyLocal.getUserLocal(), dBObjectLocal);
                changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.FIRST_NAME, p_personValue.getFirstName());
                changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.LAST_NAME, p_personValue.getLastName());
                changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.JOB_TITLE, p_personValue.getJobTitle());
                changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.DESCRIPTION, nodeValue.getDescription());
                changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.PARENT_NODE, p_parentNodeLocal.getPathName());
                ContactableSessionUtil.getLocalHome().create().addContactDetailDeltas(changeDeltaLocal, contactableValue);
                return personLocal;
            }
            else
                throw new PermissionDeniedException();
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to edit the person then do so and log the
     * changes with an appropriate ChangeDelta.
     *
     * @param p_key User's security key
     * @param p_person The Person object being editted
     * @param p_personValue The value details for the Person part of the person
     *
     * @ejb.interface-method view-type="local"
     **/
    public void editPerson(KeySessionLocal p_keyLocal,
                           PersonLocal p_personLocal,
                           com.velocityme.valueobjects.PersonValue p_personValue)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            ContactableLocal contactableLocal = p_personLocal.getContactableLocal();
            NodeLocal nodeLocal = contactableLocal.getNodeLocal();
            if (m_searchSessionLocal.getAssignedPermissionsLocal(p_keyLocal, nodeLocal).contains(m_permissionPersonEdit)) {
                ContactableValue contactableValue = p_personValue.getContactableValue();
                NodeValue nodeValue = contactableValue.getNodeValue();
                nodeValue.setName(p_personValue.getFirstName() + " " + p_personValue.getLastName());
                ChangeDeltaLocal changeDeltaLocal = ChangeDeltaUtil.getLocalHome().create(new Date(), ChangeDeltaTypeBean.EDIT, p_keyLocal.getUserLocal(), nodeLocal.getDBObjectLocal());
                if (!p_personValue.getFirstName().equals(p_personLocal.getFirstName()))
                    changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.FIRST_NAME, p_personValue.getFirstName());
                if (!p_personValue.getLastName().equals(p_personLocal.getLastName()))
                    changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.LAST_NAME, p_personValue.getLastName());
                if (!p_personValue.getJobTitle().equals(p_personLocal.getJobTitle()))
                    changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.JOB_TITLE, p_personValue.getJobTitle());
                if (!nodeValue.getDescription().equals(nodeLocal.getDescription()))
                    changeDeltaLocal.addItem(ChangeDeltaItemTypeBean.DESCRIPTION, nodeValue.getDescription());
                ContactableSessionUtil.getLocalHome().create().calcContactDetailChanges(contactableValue, contactableLocal.getContactDetailsLocal());
                ContactableSessionUtil.getLocalHome().create().addContactDetailDeltas(changeDeltaLocal, contactableValue);
                nodeLocal.setNodeValue(nodeValue);
                contactableLocal.setContactableValue(contactableValue);
                p_personLocal.setPersonValue(p_personValue);
            }
            else
                throw new PermissionDeniedException();
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(CreateException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * If the user has permission to access a person then return the local object.
     *
     * @param p_key User's security key
     * @param p_personPK The Person object to lookup
     *
     * @ejb.interface-method view-type="local"
     **/
    public PersonLocal getPersonLocal(KeySessionLocal p_keyLocal, 
                                      PersonPK p_personPK)
        throws PermissionDeniedException, InvalidKeyException {
        try {
            PersonLocal personLocal = PersonUtil.getLocalHome().findByPrimaryKey(p_personPK);
            NodeLocal nodeLocal = personLocal.getContactableLocal().getNodeLocal();
            if (m_searchSessionLocal.getAssignedPermissionsLocal(p_keyLocal, nodeLocal).contains(m_permissionNodeView)) {
                return personLocal;
            }
            else
                throw new PermissionDeniedException();
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * Get the full list of person value objects.
     *
     * @param p_key User's security key
     *
     * @ejb.interface-method view-type="local"
     **/
    public java.util.Collection getAllValueObjects(KeySessionLocal p_keyLocal) throws InvalidKeyException {
        Collection values = new java.util.TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                PersonValue p1 = (PersonValue)o1;
                PersonValue p2 = (PersonValue)o2;
                return p1.getContactableValue().getNodeValue().getName().compareTo(p2.getContactableValue().getNodeValue().getName());
            }
        });
        try {
            if (p_keyLocal.isValid()) {
                Collection persons = PersonUtil.getLocalHome().findAll();
                Iterator i = persons.iterator();
                while(i.hasNext()) {
                    PersonLocal personLocal = (PersonLocal)i.next();
                    values.add(new PersonValueToString(personLocal.getPersonValue()));
                }
            }
            else
                throw new InvalidKeyException();
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
        return new ArrayList(values);
    }
    
    /**
     * Get the list of user value objects for a particular person.
     *
     * @param p_key User's security key
     * @param p_person Person whose users are required
     *
     * @ejb.interface-method view-type="local"
     **/
    public java.util.Collection getUserValueObjects(KeySessionLocal p_keyLocal, PersonLocal p_personLocal) throws InvalidKeyException {
        Collection values = new java.util.ArrayList();
        if (p_keyLocal.isValid()) {
            Collection users = p_personLocal.getUsersLocal();
            Iterator i = users.iterator();
            while(i.hasNext()) {
                UserLocal userLocal = (UserLocal)i.next();
                values.add(userLocal.getUserValue());
            }
        }
        else
            throw new InvalidKeyException();
        return values;
    }
    
    /**
     * Get the list of time value objects for the given person on the given day
     *
     * @param p_key User's security key
     * @param p_personLocal Person that the times are required for
     * @param p_start Start date for range that the times are required for
     * @param p_stop Stop date for range that the times are required for
     *
     * @ejb.interface-method view-type="local"
     **/
    public java.util.Collection getTimeValues(KeySessionLocal p_keyLocal, PersonLocal p_personLocal, Date p_start, Date p_stop) throws InvalidKeyException {
        Collection values = new java.util.ArrayList();
        if (p_keyLocal.isValid()) {
            try {
                List timeLocals = new ArrayList(TimeUtil.getLocalHome().findPersonTimeByDate(p_personLocal, p_start, p_stop));
                Collections.sort(timeLocals, new Comparator() {
                    public int compare(Object o1, Object o2) {
                        return ((TimeLocal)o1).getStopTime().compareTo(((TimeLocal)o2).getStopTime());
                    }
                });
                Iterator i = timeLocals.iterator();
                while(i.hasNext()) {
                    TimeLocal timeLocal = (TimeLocal)i.next();
                    values.add(timeLocal.getTimeValue());
                }
            }
            catch(NamingException e) {
                throw new EJBException(e);
            }
            catch(FinderException e) {
                throw new EJBException(e);
            }
        }
        else
            throw new InvalidKeyException();
        return values;
    }
    
    /**
     * Create the Session Bean.
     * @throws CreateException 
     * @ejb:create-method view-type="remote"
     */
    public void ejbCreate() throws CreateException {
        try {
            m_searchSessionLocal = SearchSessionUtil.getLocalHome().create();
            m_permissionPersonCreate = PermissionUtil.getLocalHome().findByPrimaryKey(new PermissionPK(new Integer(PermissionBean.PERSON_CREATE)));
            m_permissionPersonEdit = PermissionUtil.getLocalHome().findByPrimaryKey(new PermissionPK(new Integer(PermissionBean.PERSON_EDIT)));
            m_permissionNodeView = PermissionUtil.getLocalHome().findByPrimaryKey(new PermissionPK(new Integer(PermissionBean.NODE_VIEW)));
        }
        catch(NamingException e) {
            throw new CreateException(e.getMessage());
        }
        catch(FinderException e) {
            throw new CreateException(e.getMessage());
        }
    }

    public void ejbActivate() throws java.rmi.RemoteException {
    }
    
    public void ejbPassivate() throws java.rmi.RemoteException {
    }
    
    public void ejbRemove() throws java.rmi.RemoteException {
    }
    
    public void setSessionContext(javax.ejb.SessionContext sessionContext) throws java.rmi.RemoteException {
        m_context = sessionContext;
    }
    
}
